import { createDiscreteApi } from 'naive-ui'

export interface Result<T> {
  code: number
  msg: string
  data: T
}
const request = <T = any>(
  url: string,
  params: any,
  customOptions: Record<string, any>
): Promise<T> => {
  const { proxyURL } = useRuntimeConfig().public
  const tokenCookie = useCookie('token')
  const router = useRouter()
  const { message } = createDiscreteApi(['message'])
  return new Promise((resolve, reject) => {
    useFetch(url, {
      baseURL: ('http://localhost:3000/' + proxyURL) as string,
      method: customOptions.method,
      headers: {
        Authorization: tokenCookie.value || ''
      },
      params: ['POST', 'PUT'].includes(customOptions.method) ? undefined : params,
      body: ['POST', 'PUT'].includes(customOptions.method) ? params : undefined,
      ...customOptions,
      // 处理响应数据
      onResponse({ response }) {
        const { code, msg, status } = response._data

        if (status === 404) return
        switch (code) {
          case 401:
            message.error(msg || '未登录')
            tokenCookie.value = null
            router.push({ path: '/login' })
            break
          case 500:
            message.error(msg || '服务器错误')
            break
          default:
            resolve(response._data)
            break
        }
      },
      // 处理请求错误
      onRequestError({ error }) {
        reject(error)
      },
      // 处理响应错误
      onResponseError({ response }) {
        message.error(response.statusText)
        reject(response.statusText)
      }
    })
  })
}

export const http = {
  get: function <T = any>(
    url: string,
    query?: any,
    options?: Record<string, any>
  ): Promise<Result<T>> {
    return request(url, query, { method: 'GET', ...options }) as Promise<Result<T>>
  },
  post: function <T = any>(
    url: string,
    body?: any,
    options?: Record<string, any>
  ): Promise<Result<T>> {
    return request(url, body, { method: 'POST', ...options }) as Promise<Result<T>>
  },
  put: function <T = any>(
    url: string,
    body?: any,
    options?: Record<string, any>
  ): Promise<Result<T>> {
    return request(url, body, { method: 'PUT', ...options }) as Promise<Result<T>>
  },
  delete: function <T = any>(
    url: string,
    query?: any,
    options?: Record<string, any>
  ): Promise<Result<T>> {
    return request(url, query, { method: 'DELETE', ...options }) as Promise<Result<T>>
  }
}
